﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.UI.WebControls;
using System.Web.UI;
using System.Text.RegularExpressions;
using System.ServiceModel.Activation;
using Medianamik.Globalization;
using System.Configuration;
using Medianamik.Core.Configuration;
using Medianamik.Core;
using System.Web;
using System.Reflection;

namespace Medianamik.UI.Lock
{
    public class LockActivator : WebControl  , IPostBackEventHandler, IScriptControl 
    {
        private static readonly MedianamikConfigSection _config = (MedianamikConfigSection)ConfigurationManager.GetSection(ConfigurationSectionName.MEDIANAMIK);
        public static bool LockEnabled
        {
            get
            {
                return _config.EnableLock;
            }
        }

        #region UltimatumReached Event

        private static readonly object _ultimatumReached = new object();
        public event EventHandler UltimatumReached
        {
            add
            {
                Events.AddHandler(_ultimatumReached, value);
            }
            remove
            {
                Events.RemoveHandler(_ultimatumReached, value);
            }
        }

        protected void OnUltimatumReached(EventArgs e)
        {
            var handler = Events[_ultimatumReached] as EventHandler;
            if (Enabled && handler != null)
            {
                handler(this, e);
            }
        }

        #endregion

        #region IPostBackEventHandler Members

        public void RaisePostBackEvent(string eventArgument)
        {
            if (this.Enabled)
            {
                OnUltimatumReached(EventArgs.Empty);
            }
        }

        #endregion

        public TimeSpan Period
        {
            get
            {
                return (TimeSpan?)ViewState["Period"] ?? TimeSpan.FromSeconds(10);
            }
            set
            {
                if (value <= TimeSpan.Zero)
                {
                    throw new ArgumentException("Period must be a positive value");
                }
                ViewState["Period"] = value;
            }
        }

        public Guid ObjectId
        {
            get
            {
                return (Guid?)ViewState["ObjectId"] ?? Guid.Empty;
            }
            set
            {
                ViewState["ObjectId"] = value;
            }
        }

        public string OnClientUltimatumReached
        {
            get
            {
                return ViewState["OnClientUltimatumReached"] as string ?? "function(){window.focus();alert('" + Translator.TranslateJS("Medianamik_LockManagement", "UltimatumReached") + "'); " + Page.ClientScript.GetPostBackEventReference(this, string.Empty) + ";}";
            }
            set
            {
                ViewState["OnClientUltimatumReached"] = value;
            }
        }

        protected override void OnPreRender(EventArgs e)
        {
           if (LockEnabled 
                && ObjectId != Guid.Empty
                && !this.DesignMode)
            {
                // Test for ScriptManager and register if it exists
                var sm = ScriptManager.GetCurrent(Page);
                if (sm == null)
                {
                    throw new Exception("A ScriptManager control must exist on the current page.");
                }
                sm.RegisterScriptControl(this);
                sm.Services.Add(new ServiceReference("/Medianamik/Services/LockWebService.asmx"));
            }
            base.OnPreRender(e);
        }

        protected override void Render(HtmlTextWriter writer)
        {
            if (LockEnabled 
                && ObjectId != Guid.Empty 
                && !this.DesignMode)
            {
                var sm = ScriptManager.GetCurrent(Page);
                sm.RegisterScriptDescriptors(this);
            }
            base.Render(writer);
        }

        #region IScriptControl Members

        public IEnumerable<ScriptDescriptor> GetScriptDescriptors()
        {
            ScriptControlDescriptor descriptor = new ScriptControlDescriptor("Medianamik.LockActivator", this.ClientID);
            descriptor.AddProperty("objectId", this.ObjectId.ToString());
            descriptor.AddProperty("period", this.Period.TotalMilliseconds);
            descriptor.AddScriptProperty("ultimatumReachedHandler", OnClientUltimatumReached);

            return new ScriptDescriptor[] { descriptor };
        }

        public IEnumerable<ScriptReference> GetScriptReferences()
        {
            ScriptReference reference = new ScriptReference();
            reference.Path =  Medianamik.Core.Sugar.Resources.GetWebResourceUrl("Lock.lockCycle.js", this.Page, this.GetType(), Assembly.GetAssembly(this.GetType()));
            return new ScriptReference[] { reference };
        }

        #endregion
    }
}
